(function (w) {
  /**
   * @description jsbridge操作类
   */
  const HeyheyBridge = {
    /** 
     * window.
     * @description 预置协议JS调用APP
     */
    Js2AppFunctionList: {
      setTopBarShare: "topBar:share",
      setTopBarBack: "topBar:back",
      setTopBarExplain: "topBar:explain",
      heyheytalkPath: "heyheytalk://",
      openShareBar: "shareBar:open",
      sharePictureToWx: "sharePictures",
      shareToHHmessage: "shareTo:hhmessage",
      shareToWXtimeline: "shareTo:wxtimeline",
      shareToWXmessage: "shareTo:wxmessage",
      shareToQQ: "shareTo:qq",
      shareToQzone: "shareTo:qzone",
      getHeyid: "get:heyid",  
      getToken: "get:token",
      request: "server:request",
      getUserIdAndRoom: "get:userroom",
      heyDo: "hey:do",
      goSignVerify: 'hey:signVerify',
      pageFinish: 'page:finish'
    },

    /**
     * @description 预置协议APP调用JS事件池
     * "share:hhmessage" app 分享成功
     * "share:wxtimeline" 微信朋友圈分享成功
     * "share:wxmessage" 微信消息分享成功
     * "share:qq" qq分享成功
     * "share:qzone" qq空间分享成功
     * "pay:succ" 支付成功
     */
    App2JsEventList: {
      //eg:
      // "share:hhmessage": function(data){

      // }
    },

    /**
     * @description  获取jsbridge实例, 单例
     */
    getBridge() {
      let bridge = null;
      return new Promise(function (resolve) {
        if (bridge) {
          resolve(bridge)
        } else {
          function setupHeyhey(callback) {
            if (window.WebViewJavascriptBridge) {
              return callback(WebViewJavascriptBridge);
            }
            if (window.WVJBCallbacks) {
              return window.WVJBCallbacks.push(callback);
            }
            document.addEventListener('WebViewJavascriptBridgeReady', function () {
              // callback(WebViewJavascriptBridge)
              WVJBCallbacks.forEach(function (cb) {
                cb(WebViewJavascriptBridge);
              })
            }, false);

            window.WVJBCallbacks = [callback];
            var WVJBIframe = document.createElement('iframe');
            WVJBIframe.style.display = 'none';
            WVJBIframe.src = 'https://__bridge_loaded__';
            document.documentElement.appendChild(WVJBIframe);
            setTimeout(function () { document.documentElement.removeChild(WVJBIframe) }, 0);
          }
          setupHeyhey(function (bridge) {
            bridge = bridge;
            resolve(bridge)
          })
        }
      })
    },

    /**
     * @description 对app进行实际调用 timeLong之后jsbridge没有返回，则返回null告诉调用方超时
     * @param action 
     * @param data
     * @param callback 调用app方法之后的回调处理
     */
    invokeApp(action, data, callback) {
      var end = false;
      const timeLong = 3000;
      var out = setTimeout(function () {
        if (!end) {
          console.log(`jsbrage timeout..., action: ${action}, data: ${JSON.stringify(data)}, timeLong: ${timeLong}`);
          end = true;
          callback && callback(null);
        }
      }, timeLong);
      this.getBridge().then(function (bridge) {
        bridge.callHandler('JSToHeyHeyBridge', { 'action': action, 'data': data }, function (response) {
          console.log('call end action:', action, data)
          if (!end) {
            end = true;
            clearTimeout(out);
            callback && callback(response);
          }
        });
      })
    },

    /**
     * @description 根据协议遍历注册JS调用APP
     */
    registJsToAppFunctions() {
      const { Js2AppFunctionList } = this;
      const self = this;
      for (key in Js2AppFunctionList) {
        /**
         * @param {Object} data 调用app传参 
         * @param {*} callback 调用app之后的处理逻辑
         */
        const action = Js2AppFunctionList[key];
            
        this[key] = function (data, callback) {
            self.invokeApp(action, data, callback)
        }
      }
    },

    /**
     * @description 根据协议监听APP调用JS
     */
    registAppToJsListeners() {
      const { App2JsEventList } = this;
      this.getBridge().then(function (bridge) {
        /**
         * @data app传参给js
         * @responseCallback js传参给app用于app逻辑处理
         */
        bridge.registerHandler('HeyHeyToJSBridge', function (data, responseCallback) {
          if (typeof data === 'string') {
            data = JSON.parse(data);
          }
          console.log('HeyHeyToJSBridge--------');
          // 接口定义问题
          var event = App2JsEventList[data.action || data.a];
          console.log(event);
          
          //未添加监听
          if (!event) {
            responseCallback({ 'result': 201 });
            return;
          }
          //TODO promise 改造
          event(data.data);
          responseCallback({ 'result': 0 });
        });
      })
    },

    /**
     * @description
     */
    addBridgeListener(action, callback) {
      this.App2JsEventList[action] = callback

      
    },

    /**
     * @description 初始化
     */
    init() {
      /**
       * 
       */
      this.registAppToJsListeners();
      this.registJsToAppFunctions();

    }
  };

  HeyheyBridge.init();

  window.HeyheyBridge = HeyheyBridge;

  window.isHeyHeyTalk = () => {
    if (window.navigator.userAgent.toLowerCase().match(/heyheytalk/i) == 'heyheytalk') {
      return true;
    }
    return false;
  }

})()



